home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Misc
/
Crossword
/
Source
/
PlainSquare.m
< prev
next >
Wrap
Text File
|
1992-10-12
|
4KB
|
245 lines
/*
File PlainSquare.m
Squares are the variables that guide the search. This file implements simple squares for plain depth first search.
*/
#import <appkit/appkit.h>
#import "Plain.h"
#import "Puzzle.h"
#import "Crossword.h"
#import "CrosswordSquare.h"
#import "Inspector.h"
/* ———————————————————————————————————————————————————————————————————————————— */
#define position(i) ((wordPosition *) [words elementAt: i])
#define forword(c) ((c) == WILDCARD ? (c):(c) + 'a')
#define forcell(c) ((c) == WILDCARD ? EMPTY:(c) + 'A')
/* ———————————————————————————————————————————————————————————————————————————— */
@implementation PlainSquare
- (float) efficiency { return efficiency; }
/* ———————————————————————————————————————————————————————————————————————————— */
- initPuzzle: (id) thePuzzle cell: (id) theCell
{
[super init];
puzzle = thePuzzle;
cell = theCell;
letter = WILDCARD;
tried = 0;
words = [[Storage alloc]
initCount: 0 elementSize: sizeof(wordPosition) description: ""];
return self;
}
- free
{
[words free];
[super free];
return self;
}
- addToWord: (id) word at: (int) i
{
wordPosition position;
position.word = word;
position.i = i;
[words addElement: &position];
return self;
}
- startOver
{
return self;
}
/* ———————————————————————————————————————————————————————————————————————————— */
- setStatus: (int) flag
{
status |= flag;
[self adjustColor];
return self;
}
- clearStatus: (int) flag
{
status &= ~flag;
[self adjustColor];
return self;
}
- hilight
{
[self setStatus: HILIGHT];
[[puzzle getCrossword] drawCellInside: cell];
return self;
}
- unhilight
{
[self clearStatus: HILIGHT];
[[puzzle getCrossword] drawCellInside: cell];
return self;
}
- adjustColor
{
int i, n;
n = status & ~(status - 1);
i = 0;
while (n > 0)
{
i++;
n >>= 1;
}
[cell setColor: [[puzzle getInspector] getColor: i]];
return self;
}
/* ———————————————————————————————————————————————————————————————————————————— */
- (BOOL) fillNext
{
char choice;
if ((choice = [self chooseLetter]) == WILDCARD) [self clear];
[[self setLetter: choice] show];
return (letter == WILDCARD) ? NO:YES;
}
- erase
{
[[[self clear] setLetter: WILDCARD] show];
return self;
}
- clear
{
letter = WILDCARD;
tried = 0;
return self;
}
- show
{
[[puzzle getCrossword] putLetter: forcell(letter) inSquare: cell];
DPSFlush();
return self;
}
- setLetter: (char) theLetter
{
wordPosition * position;
int i;
if ((letter = theLetter) != WILDCARD) tried |= (1 << letter);
i = [words count];
while (i--)
{
position = position(i);
[position->word changeLetter: position->i to: forword(letter)];
}
return self;
}
- (char) chooseLetter
{
int i, max;
char best;
BOOL findbest;
best = WILDCARD;
findbest = [[puzzle getInspector] getOption: BESTLETTER];
for (max = 0, i = 0; i < LETTERS; i++)
if ((count[i] > max) && !(tried & (1 << i)))
{
max = count[i];
best = i;
if (!findbest) break;
}
return best;
}
/* ———————————————————————————————————————————————————————————————————————————— */
- update
{
wordPosition * position;
countTable table;
int i, j;
if (letter == WILDCARD)
{
for (j = 0; j < LETTERS; j++) count[j] = 1;
i = [words count];
while (i--)
{
position = position(i);
table = [position->word getCount];
for (j = 0; j < LETTERS; j++) count[j] *= table[position->i][j];
}
for (i = 0, j = 0; j < LETTERS; j++) i += (count[j] != 0);
if ([[puzzle getInspector] getOption: BESTSQUARE])
efficiency = 1.0 / (i + 1.0); else
efficiency = (i == 0) + 1.0;
}
return self;
}
@end